<?php
class FrontRenderer extends Renderer
{	

	/**
	 * 
	 * @var boolean
	 */
	public $clearRender = false;
	
	/**
	 * 
	 * @var string
	 */
	public $baseDirectory;
		
	/**
	 * 
	 * @var string
	 */
	public $subdirectory = '';
	
	/**
	 * 
	 * Where to cache output
	 * @var string
	 */
	public $path;
	
	/**
	 * 
	 * @var string
	 * @var int
	 */
	public $template;	
	
	public function __construct()
	{		
		
		parent::__construct();
		if($_GET['clear'] && $_GET['clearall'])
		{
			recursive_remove_directory($this->baseDirectory);
		}
	}
	
	public function setSubject($subject)
	{
		$this->subject = $subject;
	}
	
	
	/**
	 * 
	 */
	public function showIndex()
	{	
		$this->redirect('/puzzle');
		$this->path =  '/index';
		
		$this->renderOutput();
	}
	
	public function showLogout()
	{
		User::logout();
		$this->redirect('/login'); 
	}
	
	public function showUser()
	{
		$oUser = User::getLoggedIn();
		
		if(!$oUser)
		{
			$this->redirect('/login');
		}
		
		$aSolutions = Solution::getAll(array('user_id' => $oUser->getId(), 'confirmed' => 'CONFIRMED'), 'date', 'desc');
		$aPendingSolutions = Solution::getAll(array('user_id' => $oUser->getId(), 'confirmed' => 'NOTCONFIRMED'), 'date', 'desc');
		$aOwnPuzzles = Puzzle::getAll(array('user_id' => $oUser->getId()), 'date', 'desc');
		$aOpenPuzzles = Puzzle::getAllFromQuery("SELECT Puzzle.id
													FROM Puzzle
													WHERE Puzzle.id NOT IN
													(
														SELECT Solution.puzzle_id 
														FROM
															Solution
														WHERE 
															Solution.user_id = '" . $oUser->getId() . "'
													)
													AND Puzzle.user_id != '" . $oUser->getId() . "'");
		$this->assign('aOpenPuzzles', $aOpenPuzzles);		
		$this->assign('aOwnPuzzles', $aOwnPuzzles);		
		$this->assign('aSolutions', $aSolutions);		
		$this->assign('aPendingSolutions', $aPendingSolutions);		
						
		$this->renderOutput();
	}
	
	public function showPuzzle()
	{
		if($this->action)
		{
			$method = 'action' . $this->subject . ucfirst($this->action);
			
			if(method_exists($this, $method))
			{
				
				$this->$method();
			}
			else 
			{
				$this->redirect('/'.$this->subject);
			}
		}
		else
		{
			$aPuzzles = Puzzle::getAll(array(), 'date', 'desc');
			$this->assign('aPuzzles', $aPuzzles);
		}
		$this->renderOutput();
	}
	
	protected function actionPuzzleView()
	{
		$oPuzzle = new Puzzle($this->viewId);
		
		$this->template = 'view.tpl';
		$this->assign('oPuzzle', $oPuzzle);
		
		$oUser = User::getLoggedIn();		
		if($oUser)
		{
			$oCorrectSolution = $oPuzzle->getIsSolvedByUser($oUser->getId()); 
			$oPendingSolution = $oPuzzle->userHasPendingSolution($oUser->getId()); 
			$ownPuzzle = $oUser->getId() == $oPuzzle->user_id;
			$this->assign('oCorrectSolution', $oCorrectSolution);
			$this->assign('oPendingSolution', $oPendingSolution);
			$this->assign('ownPuzzle', $ownPuzzle);
			
			if(!$oOldSolution && !$oPendingSolution && !$ownPuzzle)
			{
				$form = new Form();
				
				$inputAnswer = new TextArea('answer');
				$inputAnswer->addValidator(new LengthValidator(true, 1, 1000));
				$form->addElement($inputAnswer, 'Je antwoord (kort)');		
				
				$inputAnswerinfo = new TextArea('answerinfo');
				$inputAnswerinfo->addValidator(new LengthValidator(false, 1, 1000));
				$form->addElement($inputAnswerinfo, 'Eventuele onderbouwing over je antwoord');
				
				$this->assign('form', $form);
				
				
				if($form->isPosted())
				{
					$form->validate();
					$formErrors = array();
					if($form->getErrors())
					{
						$formErrors = $form->getErrors();		
						$hasErrors = true;		
					}
								
					if(!$hasErrors)
					{
						$oSolution = new Solution();
						$oSolution->puzzle_id = $oPuzzle->getId();
						$oSolution->user_id = $oUser->getId();
						$oSolution->answer = $inputAnswer->getValue();
						$oSolution->answerinfo = $inputAnswerinfo->getValue();					
						
						if(!$oPuzzle->answerneedsvalidation)
						{
							$answerUser = trim(strtolower($inputAnswer->getValue()));
							$answerPuzzle = trim(strtolower($oPuzzle->answer));
							
							if($answerUser == $answerPuzzle)
							{
								$oSolution->confirmed = 'CONFIRMED';
								$success = true;
							}
							else
							{
								$oSolution->confirmed = 'DENIED';							
								$denied = true;
							}
						}
						else
						{
							$needtoconfirm = true;
						}
						$oSolution->save();	
						$oSolution = new Solution($oSolution->getId());
						if($success)
						{
							$oCorrectSolution = $oSolution;	
							$this->assign('oCorrectSolution', $oCorrectSolution);
						}
						elseif($needtoconfirm)
						{
							$oPendingSolution = $oSolution;	
							$this->assign('oPendingSolution', $oPendingSolution);
							
						}
						$this->assign('failed', $denied);					
						$this->assign('success', $success);					
						$this->assign('needtoconfirm', $needtoconfirm);					
					}
					
					
					$this->assign('hasErrors', $hasErrors);
					$this->assign('errors', $formErrors);
				}
			}
			
			if($oCorrectSolution || $ownPuzzle)
			{
				$this->assign('allowShowAnswer', true);
			}
			
		}
		
	}
	
	protected function actionPuzzleAdd()
	{
		$oUser = User::getLoggedIn();		
		if(!$oUser)
		{
			$this->redirect('/puzzle');
		}
		
		
		$form = new Form();
		
		$inputName = new InputText('name');
		$inputName->addValidator(new LengthValidator(true, 10, 255));
		$form->addElement($inputName, 'Naam van het raadsel');
		
		$inputDescription = new TextArea('description');
		$inputDescription->addValidator(new LengthValidator(true, 20, 1200));
		$form->addElement($inputDescription, 'Het raadsel');
				
		$inputAnswer = new TextArea('answer');
		$inputAnswer->addValidator(new LengthValidator(true, 1, 1000));
		$form->addElement($inputAnswer, 'Het antwoord (kort)');				
				
		
		$inputAnswerneedsvalidation = new RadioBoolean('answerneedsvalidation');
		$form->addElement($inputAnswerneedsvalidation, "Moeten de antwoorden gecontroleerd worden? (Kies 'Nee' bij exacte antwoorden als '10', 'ja', 'rood' etc)");
		
		$inputAnswerinfo = new TextArea('answerinfo');
		$inputAnswerinfo->addValidator(new LengthValidator(false, 1, 1000));
		$form->addElement($inputAnswerinfo, 'Eventuele extra uitleg over het antwoord');
				
		
		$numHints = 5; 
		$hintInputs = array();
		for($i = 1; $i <= $numHints; $i++)
		{
			$inputHint = new InputText('hint_'.$i);
			$inputHint->addValidator(new LengthValidator(false, 1, 255));
			$inputHintDesc = 'Hint '.$i;
			if($i == 1)
			{
				$inputHintDesc = "Je kunt hier eventueel hints toevoegen. De gebruiker kan dan op de knop 'Toon hint' klikken om een van onderstaande hints te onthullen<br /><br />" . $inputHintDesc;
			}
			$form->addElement($inputHint, $inputHintDesc);
			$hintInputs[] = $inputHint;
		}
		
		

		
		$this->template = '../form/default.tpl';
		$this->assign('form', $form);
		$this->assign('formTitle', 'Raadsel toevoegen');
		
		if($form->isPosted())
		{
			$form->validate();
			$formErrors = array();
			if($form->getErrors())
			{
				$formErrors = $form->getErrors();		
				$hasErrors = true;		
			}
			elseif(Puzzle::getSingle(array('name' => $inputName->getValue())))
			{
				$formErrors[] = "Er bestaat al een raadsel met deze naam"; 
				$hasErrors = true;		
			}

						
			if(!$hasErrors)
			{
				// aanmaken!
				$oPuzzle = new Puzzle();
				$oPuzzle->name = $inputName->getValue();
				$oPuzzle->user_id = $oUser->getId();
				$oPuzzle->description = $inputDescription->getValue();
				$oPuzzle->answer = $inputAnswer->getValue();
				$oPuzzle->answerneedsvalidation = $inputAnswerneedsvalidation->getValue();
				$oPuzzle->answerinfo = $inputAnswerinfo->getValue();
				$oPuzzle->save();
				
				foreach ($hintInputs as $orderweight => $inputHint)
				{
					if($inputHint->getValue())
					{
						$oHint = new Hint();
						$oHint->puzzle_id = $oPuzzle->getId();
						$oHint->orderweight = $orderweight;
						$oHint->description = $inputHint->getValue();
						$oHint->save();
					}					
				}			
				$this->assign('oPuzzle', $oPuzzle);
				$this->template = 'add.confirm.tpl';
			}
			
			
			$this->assign('hasErrors', $hasErrors);
			$this->assign('errors', $formErrors);
		}		
		
		$this->renderOutput();
	}
	
	public function showLogin()
	{
		$form = new Form();
		
		$inputEmail = new InputText('email');
		$inputEmail->addValidator(new EmailValidator());
		$form->addElement($inputEmail, 'E-mailadres');
		
		$inputPassword = new InputPassword('password');
		$inputPassword->addValidator(new Validator());
		$form->addElement($inputPassword, 'Wachtwoord');
		
		$form->setSubmitButtonLabel('Inloggen');
		
		$this->template = '../form/default.tpl';
		$this->assign('form', $form);
		$this->assign('formTitle', 'Inloggen');
		
		if($form->isPosted())
		{
			$form->validate();
			if($form->getErrors())
			{
				$formErrors = $form->getErrors();				
			}
			else
			{
				if(User::login($inputEmail->getValue(), $inputPassword->getValue()) == false)
				{
					$formErrors[] = "Combinatie van email en wachtwoord niet gevonden";
				}
			}
			
			if(count($formErrors))
			{;
				$hasErrors = true;
			}
			else
			{			
				// ingelogd!
				$this->redirect('/user');				
			}
			
			$this->assign('hasErrors', $hasErrors);
			$this->assign('errors', $formErrors);
		}		
		
		$this->renderOutput();
	}
	public function showRegister()
	{
		$form = new Form();
		
		$inputEmail = new InputText('email');
		$inputEmail->addValidator(new EmailValidator());
		$form->addElement($inputEmail, 'E-mailadres');
		
		$inputPassword = new InputPassword('password');
		$inputPassword->addValidator(new Validator());
		$form->addElement($inputPassword, 'Wachtwoord');
		
		$inputPasswordConfirm = new InputPassword('passwordConfirm');
		$inputPasswordConfirm->addValidator(new Validator());
		$form->addElement($inputPasswordConfirm, 'Bevestiging wachtwoord');
		
		$inputFirstname = new InputText('firstname');
		$inputFirstname->addValidator(new Validator());
		$form->addElement($inputFirstname, 'Voornaam');
		
		$inputLastname = new InputText('lastname');
		$inputLastname->addValidator(new Validator());
		$form->addElement($inputLastname, 'Achternaam');
		
		$form->setSubmitButtonLabel('Aanmelden');
		
		$this->template = '../form/default.tpl';
		$this->assign('form', $form);
		$this->assign('formTitle', 'Aanmelden');
		
		if($form->isPosted())
		{
			$form->validate();
			if($form->getErrors())
			{
				$formErrors = $form->getErrors();				
			}
			else
			{
				// Save feedback
				$email = $inputEmail->getValue();
				$user = User::getSingle(array('email' => $email));
				if($user instanceof  User)
				{
					$formErrors[] = "'$email' is al gebruikt";
				}
				
				if($inputPassword->getValue() != $inputPasswordConfirm->getValue())
				{
					$formErrors[] = "Wachtwoord komt niet overeen met bevestiging";					
				}
			}
			
			if(count($formErrors))
			{
				$hasErrors = true;
			}
			else
			{
				// aanmaken!
				$oUser = new User();
				$oUser->email = $inputEmail->getValue();
				$oUser->password = sha1(md5($inputPassword->getValue() .'eerstesalt') .'tweedesalt');
				$oUser->firstname = $inputFirstname->getValue();
				$oUser->lastname = $inputLastname->getValue();
				$oUser->save();
				$this->assign('oUser', $oUser);
				$this->template = 'confirm.tpl';
			}
			
			$this->assign('hasErrors', $hasErrors);
			$this->assign('errors', $formErrors);
		}		
		
		$this->renderOutput();
	}

	/**
	 * 
	 * Show/handle feedback form
	 */
	public function showFeedback()
	{		
		$form = new Form();		
		
		$inputName = new InputText('name');
		$inputName->addValidator(new Validator());
		$form->addElement($inputName, 'Naam (verplicht)');
		
		$inputEmail = new InputText('email');
		$inputEmail->addValidator(new EmailValidator(false));
		$form->addElement($inputEmail, 'E-mailadres (niet verplicht)');
		
		$inputMessage = new TextArea('comment');
		$inputMessage->addValidator(new LengthValidator(true, 20, 1000));
		$form->addElement($inputMessage, 'Feedback (verplicht)');

		$this->assign('form', $form);
		$this->template = '/feedback/feedback.form.tpl';
		
		// Validate if this form has just been posted
		if($form->isPosted())
		{
			$form->validate();
			
			if($form->getErrors())
			{
				$this->assign('hasErrors', true);
				$this->assign('errors', $form->getErrors());
			}
			else
			{
				// Save feedback
				$oFeedback = new Feedback();
				$oFeedback->name = htmlentities($inputName->getValue());
				$oFeedback->email = htmlentities($inputEmail->getValue());				
				$oFeedback->message = htmlentities($inputMessage->getValue());				
				$oFeedback->ip = $_SERVER['REMOTE_ADDR'];
				$oFeedback->save();
				$this->assign('feedback', $oFeedback);
				$this->template = '/feedback/feedback.confirm.tpl';
			}
		}

		$this->assignSettings();
		$this->smarty->display('templates' . $this->template);
		
	}

	
	
	/**
	 * (non-PHPdoc)
	 * @see Renderer::renderOutput()
	 */
	public function renderOutput()
	{		
		$this->assign('subject', $this->subject);		
		$this->assign('action', $this->action);		
		$this->assign('oUser', User::getLoggedIn());				
		$output = $this->smarty->display($this->subject . '/' . $this->template);
		exit;
	}
}